﻿--[[
   @brief    descprtion
   @author   vincentlao
   @version  1.0
   @date     2015-07-09
--]]

friend_list_control = 
{
    oss_vip_info_ = {};
    connoisseur_info_ = {}; -- 鉴赏家等级

    init = function()
        base_utility.log("friend_list_control init");
        ierd_tgp.tpf_ui.Require("social\\friend_list\\view.lua");
        ierd_tgp.tpf_ui.Require("social\\friend_list\\model.lua");
        ierd_tgp.tpf_ui.Require("social\\friend_list\\friend_list.lua");
        ierd_tgp.tpf_ui.Require("social\\friend_list\\friend_guide.lua");

        comm_center.reg_service('i_service_social_get_oss_vip_info', friend_list_control.service_social_get_oss_vip_info);
        comm_center.reg_service('i_service_social_get_vip_cached_url', friend_list_control.service_social_get_vip_cached_url);

        comm_center.reg_service('i_service_social_get_connoisseur_level_info', friend_list_control.service_social_get_connoisseur_level_info);
        comm_center.reg_service("i_service_social_get_user_detail_info", friend_list_control.on_get_friend_detail_info);

        comm_center.listen_broadcast('i_broadcast_on_last_msg', friend_list_control.on_broadcast_last_msg);

        comm_center.listen_broadcast('i_broadcast_add_new_friend', friend_list_control.on_broadcast_add_new_friend);
        comm_center.listen_broadcast('i_broadcast_del_friend', friend_list_control.on_broadcast_del_friend);        
        comm_center.listen_broadcast('i_broadcast_update_friend_online_status', friend_list_control.on_broadcast_update_friend_online_status); -- 是新IM更新游戏状态的

        local tpfui =
            base_utility.get_component_adapter("ITpf_ui",
                "ierd_tgp.tpf_ui.GetTPFUI();");
        tpfui:AddLuaListener(ierd_tgp.game_library.UPDATE_GAME_STATE, "friend_vlist_control.update_game_state");
    end;

    get_friendlist_done = function(event_id, json_str)
        base_utility.log(string.format("get_friendlist_done str = %s", json_str));
        friend_list_view.get_friendlist_done(event_id, json_str);
        comm_center.send_broadcast("i_broadcast_social_friend_list_ready", {});
        friend_list_control.request_connoisseur_vip_info();
    end;

    on_broadcast_last_msg = function(data_in)
        friend_list_model.set_last_msg(data_in.group_id, data_in.msg);

        local social_network =
            base_utility.get_component_adapter("ISocial_network",
                "ierd_tgp.social_network.Get_social_network_adapter();");
        local friends = friend_list_model.get_friend_list();
        local friend_list = {};
        for i_friend = 1, #friends do
            table.insert(friend_list, friends[i_friend].friend_id);
        end

        local table_param = {};
        table_param["id_list"] = friend_list;

        social_network:get_friend_unread_msg_num(base_utility.table_to_json(table_param));
    end;

    on_broadcast_add_new_friend = function(data_in)
        friend_list_view.on_add_new_friend(data_in.info);
    end;

    on_broadcast_del_friend = function (data_in)
        friend_list_view.on_del_friend(data_in.friend_id);
    end;

    on_broadcast_update_friend_online_status = function(data_in)
        friend_list_view.update_friend_online_status_new_im(data_in);
    end;

    service_social_get_oss_vip_info = function(param)
        return friend_list_control.oss_vip_info_;
    end;

    service_social_get_vip_cached_url = function(param)
        local vip_info = friend_list_control.oss_vip_info_;
        local vip_value = param.vip_value;

        local b_find = false;
        local vip_icon_url = '';
        if vip_info ~= nil and vip_info['data'] ~= nil then
            for i, friend_id in ipairs(vip_info['data']) do
                if friend_id['badge_type'] ~= nil then
                    if tonumber(friend_id['badge_type']) == tonumber(vip_value) then
                        b_find = true;
                        vip_icon_url = friend_id['badge_small_icon'];
                        local output = {};
                        output['vip_value'] = vip_value;
                        output['vip_icon_url'] = vip_icon_url;
                        output['vip_name'] = friend_id['badge_name'];
                        output['vip_desc'] = friend_id['badge_privilege'];
                        output['vip_from'] = friend_id['badge_source'];
                        return output;
                    end
                end
            end
        end
        return {};
    end;

    request_connoisseur_vip_info = function()
        base_utility.curl_request_async(LoadStr("CONNO_BADGE_CFG_URL"),
                                       "friend_list_control.on_get_connoisseur_vip_info",
                                        true);
    end;

    on_get_connoisseur_vip_info = function(result)
        if nil == result then
            return;
        end;
        
        local ret, ret_table = base_utility.oss_string_to_table(result, "connoisseur_badge_cfg_info");
        if ret == true then
            friend_list_control.connoisseur_info_ = ret_table;
        else
            base_utility.log("[friend_list_control]on_get_connoisseur_vip_info error:"..tostring(result));
        end
    end;

    service_social_get_connoisseur_level_info = function(param)
        local level = param.level;
        if friend_list_control.connoisseur_info_ ~= nil and 
           friend_list_control.connoisseur_info_.data ~= nil and
           type(friend_list_control.connoisseur_info_.data) == "table" then
            for k, info in pairs(friend_list_control.connoisseur_info_.data) do
                if tonumber(info.badge_type) == level then
                    return info;
                end
            end
        end
        return {};
    end;

    show = function(event_id, json_str)
        --friend_list_view.show();
    end;

    on_im_inited = function(event_id, json_str)    
        base_utility.log("[friend_list_control]on_im_inited");    
        friend_list_view.on_im_inited();
    end;

--    on_mini_mode_load_finish = function(event_id, json_str)
--        --MessageBox(root_id, friend_list_view.root_id_);
--        local param = base_utility.json_to_table(json_str);
--        if param.mainframe_mode == 1 then
--            if friend_list_view.is_mini_ui_ ~= true then
--                friend_list_view.is_mini_ui_ = true;
--                local root_id = ui_utility.uilib():GetControlIDbyCustomID(CID_MAIN_SOCIAL_FRIEND_CONTAINER_MINIUI);
--                const_ui_str, str_holder = U8toCUIStr("Ctn_MainFrameTab\\OverlapContainer_Tab\\UserObj_SocialContactList\\UserObj_SocialContactList_Imp\\Ctn_SocailListParent\\Container_1\\Obj_FriendList");
--                friend_list_view.root_id_ = ui_utility.uilib():GetControlIDbyPath(const_ui_str, root_id);
--                friend_list_view.inited_ = false;
--                friend_list_view.on_mini_mode_load_finish();
--                --MessageBox('mini');
--                if friend_list_model.mini_mode_loaded == false then
--                    base_utility.log("[friend_list_control]on_mini_mode_load_finish");
--                    friend_list_model.mini_mode_loaded = true;
--                    friend_list_view.on_mini_mode_load_finish();
--                    --[[
--                    if friend_list_model.is_get_social_test_info_ == true then
--                        friend_list_view.show_test_image(login_model.social_user_level, login_model.social_invite_code_count);
--                    end]]
--                end
--            end
--        else
--            if friend_list_view.is_mini_ui_ ~= false then
--                local root_id = ui_utility.uilib():GetControlIDbyCustomID(CID_MAIN_SOCIAL_CONTAINER_BIGUI);
--                const_ui_str, str_holder = U8toCUIStr("Ctn_MainFrameTab\\OverlapContainer_Tab\\UserObj_SocialContactList\\UserObj_SocialContactList_Imp\\Ctn_SocailListParent\\Container_1\\Obj_FriendList");
--                local id = ui_utility.uilib():GetControlIDbyPath(const_ui_str, root_id);
--                if id == 0 then
--                    --失败了，可能面板没创建（用户点击过入口才创建社交面板）
--                else
--                    friend_list_view.root_id_ = id;
--                    friend_list_view.is_mini_ui_ = false;
--                    friend_list_view.inited_ = false;
--                    friend_list_view.on_mini_mode_load_finish();
--                end;
--            end
--        end
--    end;

    on_get_my_social_test_info = function(event_id, json_str)
        base_utility.log("[friend_list_control]on_get_my_social_test_info:"..json_str);
        --[[if login_model.social_user_level > 0 then
            base_utility.log("[group_list_control]on_get_my_social_test_info have set social_user_level");
            return;
        end

        friend_list_model.is_get_social_test_info_ = true;
        if friend_list_model.mini_mode_loaded == true then
            local result_param = base_utility.json_to_table(json_str);
            local social_user_level = 0;
            local social_invite_code_count = 0;
            if result_param["result"] == 0 then
                social_user_level = result_param["level"];
                social_invite_code_count = result_param["invite_code_number"];
            end
            friend_list_view.show_test_image(social_user_level, social_invite_code_count);
        end]]
        friend_list_model.is_get_social_test_info = true;
        local result_param = base_utility.json_to_table(json_str);
        if result_param["result"] == 0 then
            friend_list_model.social_user_level = result_param["level"];
            friend_list_model.social_invite_code_count = result_param["invite_code_number"];
        end
        friend_list_view.update_ui();
    end; 

    on_friend_new_message_come = function(event_id, json_str)
        base_utility.log(string.format("on_friend_new_message_come str = %s", json_str));
        local table_param = base_utility.json_to_table(json_str);
        FriendBannerList:on_friend_new_message_come(table_param);
    end;

    on_friend_clear_message = function(event_id, json_str)
        base_utility.log(string.format("on_friend_clear_message str = %s", json_str));
        local table_param = base_utility.json_to_table(json_str);
        FriendBannerList:on_friend_clear_message(table_param.friend_id);
    end; 

    get_friendlist_detail_done = function(event_id, json_str)
        base_utility.log(string.format("get_friendlist_detail_done str = %s", json_str));
        friend_list_view.get_friendlist_detail_done(event_id, json_str);
    end;    

     get_friendlist_stutas_done = function(event_id, json_str)
        base_utility.log(string.format("get_friendlist_stutas_done str = %s", json_str));
        friend_list_view.get_friendlist_stutas_done(event_id, json_str);
    end;    

    on_get_friendlist_unread_msg_count = function(event_id, json_str)
        base_utility.log(string.format("on_get_friendlist_unread_msg_count str = %s", json_str));
        friend_list_view.on_get_friendlist_unread_msg_count(event_id, json_str);
    end;  

    on_recv_friend_report = function(event_id, json_str)
        base_utility.log(string.format("on_recv_friend_report str = %s", json_str));
        friend_list_view.on_recv_friend_report(event_id, json_str);
    end;
    
    on_add_friend_accepted = function(event_id, json_str)
        base_utility.log(string.format("on_add_friend_accepted str = %s", json_str));
        friend_list_view.on_add_friend_accepted(event_id, json_str);
    end;

    on_add_friend_accepting = function(event_id, json_str)
        base_utility.log(string.format("on_add_friend_accepting str = %s", json_str));
        friend_list_view.on_add_friend_accepting(event_id, json_str);
    end; 

    get_recommend_friend = function()
        local social_network_model =
            base_utility.get_component_adapter("ISocial_network",
                "ierd_tgp.social_network.Get_social_network_adapter();");
        social_network_model:get_recommend_friend();
    end;

    get_recommend_friend_done = function(event_id, json_str)
        base_utility.log(string.format("get_recommend_friend_done str = %s", json_str));
        local friend_tbl = base_utility.json_to_table(json_str);
        friend_guide:get_recommend_friend_rsp(friend_tbl);
    end;

    add_friend = function(friend_id, remark)
        local social_network_model =
            base_utility.get_component_adapter("ISocial_network",
                "ierd_tgp.social_network.Get_social_network_adapter();");
        social_network_model:add_friend(friend_id, remark);
        base_utility.log("[friend_list_control][add_friend]friend_id:"..tostring(friend_id)..", param:"..remark);
    end;

    add_friend_done = function(event_id, json_str)
        base_utility.log(string.format("add_friend_done str = %s", json_str));
        friend_guide:add_friend_rsp(json_str);
    end;

    on_delete_friend = function(event_id, json_str)
        base_utility.log(string.format("on_delete_friend str = %s", json_str));
        friend_list_view.on_delete_friend(event_id, json_str);
    end;

    on_send_msg_to_friend = function(msg)
        FriendBannerList:on_send_msg_to_friend(msg);
    end;

    get_all_unread_friend_id_list = function()
        local friends = {};

        local all_my_friend = friend_list_model.get_friend_list();
        if all_my_friend ~= nil then
            for i_friend = 1, #all_my_friend do
                local friend_id = all_my_friend[i_friend].friend_id;
                if talk_dialog_control.is_friend_session_opened(friend_id) == false then
                    local count = friend_list_model.get_history_unread_msg_count(friend_id);
                    if count > 0 then
                        local time = 0;
                        local last_msg = friend_list_model.get_last_msg(friend_id);
                        if last_msg ~= nil then
                            time = last_msg.time;
                        end
                        local info = {};
                        info.id = friend_id;
                        info.is_new = false;
                        info.time = time;
                        table.insert(friends, info);
                    end
                end
            end
        end
        return friends;
    end;

    get_friend_list = function()
        local all_my_friend = friend_list_model.get_friend_list();
        local ready = friend_list_model.is_get_friend_list_done;
        local data = {};
        data.ready = ready;
        data.friend_list = all_my_friend or {};
        return data;
    end;

    re_sort_friend_list = function(data_in)
        FriendBannerList:re_sort_friend();
    end;

    on_interval_to_sort_list = function (time_stamp)
        local tpfui =
            base_utility.get_component_adapter("ITpf_ui",
                "ierd_tgp.tpf_ui.GetTPFUI();");
        tpfui:RemoveInterval('friend_list_control.on_interval_to_sort_list');
        FriendBannerList:re_sort_friend();
    end;

    first_to_sort_list = true;

    on_user_info_changed = function (data)
        list = friend_list_model.is_in_friend_list(data['list_id'])
        if #list > 0 then
            data = {list_id = list};
            ret = comm_center.call_service('i_service_social_info_center_get_user_info', data);
            for index = 1, #ret['list_id'] do
                friend_list_model.update_name(ret['list_id'][index],
                 ret['list_user_info'][index]['name'],
                 ret['list_user_info'][index]['status'],
                 ret['list_user_info'][index]['url']
                 );
            end;
            
            if  #ret['list_id'] > 0 then
                local tpfui =
                    base_utility.get_component_adapter("ITpf_ui",
                        "ierd_tgp.tpf_ui.GetTPFUI();");
                if friend_list_control.first_to_sort_list then
                    friend_list_control.first_to_sort_list = false;
                    FriendBannerList:re_sort_friend();
                else
                    tpfui:RemoveInterval('friend_list_control.on_interval_to_sort_list');
                    tpfui:AddInterval('friend_list_control.on_interval_to_sort_list', 1000);
                end;
            end;
        end;
    end;

    on_lol_game_staus_changed = function(data)
        FriendBannerList:on_lol_game_staus_changed(data);
    end;

    show_msg_box_notify_reddot = function(event_id, json_str)
        friend_list_model.set_msgbox_reddot();
    end;

    clear_msg_box_notify_reddot = function(event_id, json_str)
        friend_list_model.clear_msgbox_reddot();
    end;

    on_get_title_ui_data = function ()
        friend_list_model.update_title_ui();
    end;

    on_title_mainbtn_clicked = function ()
        data = comm_center.call_service('i_service_social_mainwnd_is_shown', {});
        if data.is_show == 1 then
            friend_list_model.show_title_data_new_msg_ = false;
        else
            --有新消息的时候，如果主面板是隐藏状态，才会重新show_title_data_new_msg_
            --friend_list_model.show_title_data_new_msg_ = true;
        end

        friend_list_model.update_title_ui();
    end;

    on_mainwnd_show = function ()
        data = comm_center.call_service('i_service_social_mainwnd_is_shown', {});
        if data.is_show == 1 then
            friend_list_model.show_title_data_new_msg_ = false;
            if friend_list_view.is_mini_ui_ ~= false then
                friend_list_view.is_mini_ui_ = false;
                if 0 == friend_list_view.root_id_ then
                    local data = comm_center.call_service("i_service_social_mainwnd_get_main_dialog_id", {});
                    if nil ~= data then
                        friend_list_view.root_id_ = ui_utility.get_ctrl_id_by_path(data.main_dialog_id, 
                            "Cnt_Tabs\\Ctn_MainFrameTab\\OverlapContainer_Tab\\UserObj_SocialContactList\\UserObj_SocialContactList_Imp\\Ctn_SocailListParent\\Container_list_panel\\Obj_FriendList");
                        friend_list_view.inited_ = false;
                    end
                end

                friend_list_model.mini_mode_loaded = true;
                friend_list_view.inited_ = false;
                friend_list_view.on_mini_mode_load_finish();
            end;

        else
            --有新消息的时候，如果主面板是隐藏状态，才会重新show_title_data_new_msg_
            --friend_list_model.show_title_data_new_msg_ = true;
        end

        friend_list_model.update_title_ui();
    end;

    on_group_new_msg = function ()
        friend_list_model.on_group_new_msg();
    end;

    on_get_friend_list = function (event_id, json_str)
        local friends = {};
        local all_my_friend = friend_list_model.get_friend_list();
        if all_my_friend ~= nil then
            local count = 0;
            for i_friend = 1, #all_my_friend do
                count = count + 1;
                --[[local friend_id = all_my_friend[i_friend].friend_id;
                local info = {};
                info.id = friend_id;
                info.is_new = false;
                info.time = time;
                table.insert(friends, info);]]--
            end;
            
            local json_str = base_utility.table_to_json(all_my_friend);
            event_center.send_event(
                main_web_event.SEND_TGP_FRIEND_LIST, json_str);
        end;
    end;

    on_remote_service_get_friend_list = function(param)
        local tb_outputlist = {};
        local data = {};
        local online_list_to_send = {}; --兼容Cross的代码
        local req_game_nick_list = {};
        for index = 1, #friend_list_model.friend_table_ do
            local item = friend_list_model.friend_table_[index];
            if item ~= nil then
                local friend_item = {};
                friend_item["szId"] = item["friend_id"];
                friend_item["szShow_id"] = item["show_id"];
                friend_item["szName"] = item["name"];
                friend_item["szRemark"] = item["remark"];
                friend_item["szFace_url"] = item["url"];
                friend_item["dwExp"] = item["exp"];
                friend_item["dwGender"] = item["sex"];
                friend_item["dwLast_login_time"] = item["last_login_time"];
                friend_item["dwLevel"] = item["level"];
                friend_item["dwReg_time"] = item["reg_time"];
                friend_item["stOnline_status"] = {};
                friend_item["stOnline_status"]["dwStatus"] = item["status"];
                friend_item["stOnline_status"]["szPlaying_game"] = item["playing_game"];
                if friend_item["stOnline_status"]["dwStatus"] ~= 1 then --如果是TGP在线，就给cross做个兼容处理
                    if friend_item["stOnline_status"]["szPlaying_game"] == nil or friend_item["stOnline_status"]["szPlaying_game"] == "" then
                        --[[local playing_game = {};
                        playing_game.data = {};
                        playing_game.data.count = 1;
                        playing_game.data.list = {};
                        table.insert(playing_game.data.list, {id=55555, status=0, time=0, zone=0});
                        friend_item["stOnline_status"]["szPlaying_game"] = base_utility.table_to_json(playing_game);]]--
                        table.insert(online_list_to_send, 1, item["friend_id"]);
                    else
                        local st = base_utility.json_to_table(friend_item["stOnline_status"]["szPlaying_game"]);
                        if st["data"] == nil or st["data"]["count"] == nil or st["data"]["count"] == 0 then
                            --[[local playing_game = {};
                            playing_game.data = {};
                            playing_game.data.count = 1;
                            playing_game.data.list = {};
                            table.insert(playing_game.data.list, {id=55555, status=0, time=0, zone=0});
                            friend_item["stOnline_status"]["szPlaying_game"] = base_utility.table_to_json(playing_game);]]--
                            table.insert(online_list_to_send, 1, item["friend_id"]);
                        end
                    end
                end

                table.insert(tb_outputlist, friend_item);
                table.insert(req_game_nick_list, item["friend_id"]);
            end
        end
        data['friend_list'] = tb_outputlist;
        data['ret'] = 0;
        comm_center.send_broadcast("i_broadcast_tgp_to_app_on_get_friend_list", data);

        if nil ~= param and type(param) == 'table' and nil ~= param.game_id then
            local req_data = {
                game_id = param.game_id;
                friend_list = req_game_nick_list;
            };
            comm_center.call_service("i_service_get_game_nick_name", req_data);
        end
        

        for i = 1, #online_list_to_send do
            comm_center.send_broadcast('i_broadcast_im_on_user_status_changed', {tgp_id=online_list_to_send[i], game_id="55555", status="1", sub_status="0"}); -- to cross
        end
    end;

    on_service_get_friend_list_detail = function(friend_id_tbl)
        local tb_outputlist = {};
        local data = {};
        if type(friend_id_tbl.friend_id_list) == "table" then
            for index = 1, #friend_id_tbl.friend_id_list do
                local friend_id = friend_id_tbl.friend_id_list[index];
                local friend_item = {};
                local item = friend_list_model.get_friend_info(friend_id);
                if item ~= nil then
                    friend_item["szId"] = item["friend_id"];
                    friend_item["szShow_id"] = item["show_id"];
                    friend_item["szName"] = item["name"];
                    friend_item["szRemark"] = item["remark"];
                    friend_item["szFace_url"] = item["url"];
                    friend_item["dwExp"] = item["exp"];
                    friend_item["dwGender"] = item["sex"];
                    friend_item["dwLast_login_time"] = item["last_login_time"];
                    friend_item["dwLevel"] = item["level"];
                    friend_item["dwReg_time"] = item["reg_time"];
                    friend_item["stOnline_status"] = {};
                    friend_item["stOnline_status"]["dwStatus"] = item["status"];
                    friend_item["stOnline_status"]["szPlaying_game"] = item["playing_game"];
                    --[[if friend_item["stOnline_status"]["dwStatus"] ~= 1 then --如果是TGP在线，就给cross做个兼容处理
                        if friend_item["stOnline_status"]["szPlaying_game"] == nil or friend_item["stOnline_status"]["szPlaying_game"] == "" then
                            local playing_game = {};
                            playing_game.data = {};
                            playing_game.data.count = 1;
                            playing_game.data.list = {};
                            table.insert(playing_game.data.list, {id=55555, status=0, time=0, zone=0});
                            friend_item["stOnline_status"]["szPlaying_game"] = base_utility.table_to_json(playing_game);
                        else
                            local st = base_utility.json_to_table(friend_item["stOnline_status"]["szPlaying_game"]);
                            if st["data"] == nil or st["data"]["count"] == nil or st["data"]["count"] == 0 then
                                local playing_game = {};
                                playing_game.data = {};
                                playing_game.data.count = 1;
                                playing_game.data.list = {};
                                table.insert(playing_game.data.list, {id=55555, status=0, time=0, zone=0});
                                friend_item["stOnline_status"]["szPlaying_game"] = base_utility.table_to_json(playing_game);
                            end
                        end
                    end]]--

                    table.insert(tb_outputlist, friend_item);
                end
            end

            data['friend_list'] = tb_outputlist;
            data['ret'] = 0;
            comm_center.send_broadcast("i_broadcast_tgp_to_app_on_get_friend_detail", data);
        end
    end;

    on_get_friend_detail_info = function(data)
        if nil == data or nil == data.friend_id then
            return;
        end

        return friend_list_model.get_friend_info(data.friend_id);
    end;

    on_update_friend_remark = function(event_id, json_str)
        if nil == json_str or "" == json_str then
            return;
        end
        local param_tbl = base_utility.json_to_table(json_str);
        if nil == param_tbl or nil == param_tbl.friend_id or 
            nil == param_tbl.remark or "" == param_tbl.remark then
            return;
        end
        local updated = friend_list_model.update_remark(param_tbl.friend_id, param_tbl.remark);
        -- notify cross
        if updated then
            comm_center.send_broadcast("i_broadcast_im_on_user_profile_changed",
                                       { tgp_id = param_tbl.friend_id });
        end
    end;
};

friend_list_control.init();

--全新的虚列表friend_list
friend_vlist_control = 
{
    first_visible_item_index_ = 0;
    item_node_height_ = 58;
    is_inited_ = false;
    list_root_id_ = 0;
    timer_started_ = false;

    min_mode_root_id_ = 0;
    max_mode_root_id_ = 0;

    b_lol_state_changing_ = false;

    main_dlg_id = Tenio.INVALID_CONTROLID;

    --外部模块
    model_ = nil;
    node_ = nil;

    init = function()
        if friend_vlist_control.is_inited_ == false then
            base_utility.log("talk_dialog init");
            ierd_tgp.tpf_ui.Require("social\\friend_list\\model.lua");
            ierd_tgp.tpf_ui.Require("social\\friend_list\\friend_node.lua");
            friend_vlist_control.is_inited_ = true;

            friend_vlist_control.model_ = friend_vlist_model;
            friend_vlist_control.node_ = friend_vlist_node;
        end
    end;

    
    on_create = function (uilib, ctrl_id)
        local out = comm_center.call_service("i_service_mainframe_get_current_mode", {});
        if out.mode == 0 then --max
            friend_vlist_control.max_mode_root_id_ = ctrl_id;
            base_utility.log("[friend_vlist_control] max mode ctrl_id:"..tostring(ctrl_id));
        else
            friend_vlist_control.min_mode_root_id_ = ctrl_id;
            base_utility.log("[friend_vlist_control] mini mode ctrl_id:"..tostring(ctrl_id));
        end

        friend_vlist_control.list_root_id_ = ctrl_id;

        local tpfui =
            base_utility.get_component_adapter("ITpf_ui",
                "ierd_tgp.tpf_ui.GetTPFUI();");
        tpfui:AddInterval('friend_vlist_control.on_init', 1);
    end;

--    on_mode_load_change = function(event_id, json_str)
--        local param = base_utility.json_to_table(json_str);
--        friend_vlist_control.model_.mainframe_mode = param.mainframe_mode;

--        if param.mainframe_mode == 1 then -- mini
--            friend_vlist_control.list_root_id_ = friend_vlist_control.min_mode_root_id_;
--            base_utility.log("[friend_vlist_control] on_mode_load_change mini:"..tostring(friend_vlist_control.list_root_id_));
--        else
--            if friend_vlist_control.max_mode_root_id_ > 0 then
--                friend_vlist_control.list_root_id_ = friend_vlist_control.max_mode_root_id_;
--                base_utility.log("[friend_vlist_control] on_mode_load_change max mode:"..tostring(friend_vlist_control.list_root_id_));
--            else
--                base_utility.log("[friend_vlist_control] max mode id is not created", true);
--            end
--        end
--        -- max -> mini --> max
--        if friend_vlist_control.list_root_id_ > 0 then
--            friend_vlist_control.on_init();
--        end
--    end;

    on_init = function ()
        local tpfui =
            base_utility.get_component_adapter("ITpf_ui",
                "ierd_tgp.tpf_ui.GetTPFUI();");
        tpfui:RemoveInterval('friend_vlist_control.on_init');
        friend_vlist_control.main_dlg_id = ui_utility.get_ctrl_id_by_cid(CID_SOCIAL_PANEL_DLG);
        friend_vlist_control.first_visible_item_index_ = 0;
        friend_vlist_control.set_total_height(friend_vlist_control.model_.get_total_item_height());

        local prepared_visible_count = 20;--可视窗口的item数量
        friend_vlist_control.set_visible_window_height(prepared_visible_count * friend_vlist_control.item_node_height_);
        
        friend_vlist_control.model_.virtual_node_id_to_group_info = {};

        if friend_vlist_control.item_list_ ~= nil then
            for key,value in pairs(friend_vlist_control.item_list_) do
                -- 删除所有item数据。
                local id = value['frame_id'];
                if id~= nil then
                    layout_mgr.remove_ctrl(id);
                end;
            end;
        end;

        friend_vlist_control.item_list_ = {};

        if #friend_vlist_control.item_list_ == 0 then
            friend_vlist_control.item_list_ = {};
            for i = 1, prepared_visible_count do
                table.insert(friend_vlist_control.item_list_, {});
            end;
        end;
        friend_vlist_control.update_ui();
        friend_vlist_control.start_update_ui_timer();
    end;
    
    on_lol_game_staus_changed = function()
        friend_vlist_control.b_lol_state_changing_ = true;
    end;

    start_update_ui_timer = function()
        --[[if friend_vlist_control.model_.get_group_list_done == false then
            base_utility.log("[friend_vlist_control] start_update_ui_timer get_group_list_done false!", true);
            return;
        end]]--
        if friend_vlist_control.timer_started_ == false then
            friend_vlist_control.timer_started_ = true;
            local tpfui =
                base_utility.get_component_adapter("ITpf_ui",
                    "ierd_tgp.tpf_ui.GetTPFUI();");
            tpfui:AddInterval('friend_vlist_control.on_timer', 1000);
            base_utility.log("[friend_vlist_control] start_update_ui_timer success!", true);
        end
    end;

    stop_update_ui_timer = function()
        local tpfui =
            base_utility.get_component_adapter("ITpf_ui",
                "ierd_tgp.tpf_ui.GetTPFUI();");
        tpfui:RemoveInterval('friend_vlist_control.on_timer');
    end;

    on_timer = function()
        if Tenio.INVALID_CONTROLID ~= friend_vlist_control.main_dlg_id and
                not ui_utility.is_visible(friend_vlist_control.main_dlg_id) then
            return;
        end;
        local id_container = ui_utility.get_ctrl_parent_id(friend_vlist_control.list_root_id_);
        if id_container ~= nil then
            local container = ui_utility.get_ctrl_ptr_by_id(id_container);
            local p_rc = container:GetRectEx(FALSE,TRUE);
            if p_rc.top ~= 0 then --有个bug，窗口隐藏再显示出来，top就变成0了，这时候不要移动stack，否则位置不对
                local ptr_stack = ui_utility.get_ctrl_ptr_by_id(friend_vlist_control.list_root_id_);
                local rect = ptr_stack:GetRectEx(FALSE,TRUE);
                if rect.top ~= friend_vlist_control.stack_rect_top_ then
                    rect.left = friend_vlist_control.stack_rect_left_;
                    rect.top = friend_vlist_control.stack_rect_top_;
                    rect.right = friend_vlist_control.stack_rect_right_;
                    rect.bottom = friend_vlist_control.stack_rect_bottom_;
                    if rect.right ~= 0 then
                        ptr_stack:MoveEx(rect,TRUE);
                    end;
                end;
            end;
        end;
        if group_list_model.data_refreshed_ == nil then
        group_list_model.data_refreshed_ = {};
        end;
        if friend_list_model.data_refreshed_ == nil then
            friend_list_model.data_refreshed_ = {};
        end;

        if group_list_model.data_refreshed_['friend_list'] == nil or friend_list_model.data_refreshed_['friend_list'] == nil then
            group_list_model.data_refreshed_['friend_list'] = true;
            friend_list_model.data_refreshed_['friend_list'] = true;
        else
            -- 1.单独考虑LOL游戏详细状态的场景,游戏状态只有friend列表在实时更新
            if friend_vlist_control.b_lol_state_changing_ == true then
                friend_vlist_control.b_lol_state_changing_ = false; --2.有状态更新就需要让逻辑代码继续走下去
            else
                -- 3.否则就不用更新直接返回了
                return;
            end;
        end;
        base_utility.log("[friend_list_control]auto_update_vlist");
        friend_vlist_control.update_ui();
    end;
    
    set_visible_window_height = function(total_height)
        ui_utility.setproperty_by_id(friend_vlist_control.list_root_id_,'Height', total_height);
    end;

    set_total_height = function(total_height)
        local id_back_panel = ui_utility.get_ctrl_parent_id(friend_vlist_control.list_root_id_);
        ui_utility.setproperty_by_id(id_back_panel,'Height', total_height);
    end;

    b_doing = false;
    time_of_last_doing = 0;

    stack_rect_left_ = 0;
    stack_rect_top_ = 0;
    stack_rect_right_ = 0;
    stack_rect_bottom_ = 0;
    on_test_scroll = function (a,b,c,d,e,args)
        -- local id_stack_panel = ui_utility.get_ctrl_id_by_cid(friend_vlist_control.list_root_id_);
        local id_scrollview = ui_utility.get_ctrl_parent_id(ui_utility.get_ctrl_parent_id(friend_vlist_control.list_root_id_));
        local scroll_view = ui_utility.get_ctrl_ptr_by_id(id_scrollview);        
        local vbar = scroll_view:GetVScrollBar();
        friend_vlist_control.last_step_index_ = vbar:GetScrollPos();
        local offset = friend_vlist_control.last_step_index_ * 20;

        friend_vlist_control.first_visible_item_index_ = friend_vlist_control.model_.first_visible_item_index(offset);
        local first_item_offset = friend_vlist_control.model_.offset_of_first_visible_item_index(friend_vlist_control.first_visible_item_index_);

        --ui_utility.setproperty_by_id(friend_vlist_control.list_root_id_,'YOffset', first_item_offset);--todu
        local ptr_stack = ui_utility.get_ctrl_ptr_by_id(friend_vlist_control.list_root_id_);
        local rect = ptr_stack:GetRectEx(FALSE,TRUE);
        local height = rect.bottom - rect.top;
        rect.top = first_item_offset;
        rect.bottom = rect.top + height;

        friend_vlist_control.stack_rect_left_ = rect.left;
        friend_vlist_control.stack_rect_top_ = rect.top;
        friend_vlist_control.stack_rect_right_ = rect.right;
        friend_vlist_control.stack_rect_bottom_ = rect.bottom;
        ptr_stack:MoveEx(rect,TRUE);

        if friend_vlist_control.b_doing == false and os.clock() - friend_vlist_control.time_of_last_doing > 1 then
            friend_vlist_control.b_doing = true;
            friend_vlist_control.update_ui();
            friend_vlist_control.b_doing = false;
            friend_vlist_control.time_of_last_doing = os.clock();
        else
            local tpfui =
                base_utility.get_component_adapter("ITpf_ui",
                    "ierd_tgp.tpf_ui.GetTPFUI();");
            tpfui:AddInterval('friend_vlist_control.do_scrolled_data', 0);
        end;
        --friend_vlist_control.update_ui();
    end;
    
    item_list_ = {};
    
    do_scrolled_data = function()
        local tpfui =
            base_utility.get_component_adapter("ITpf_ui",
                "ierd_tgp.tpf_ui.GetTPFUI();");
        tpfui:RemoveInterval('friend_vlist_control.do_scrolled_data');
        friend_vlist_control.update_ui();
        friend_vlist_control.b_doing = false;
        friend_vlist_control.time_of_last_doing = os.clock();
    end;

    update_ui = function (args)
        friend_vlist_control.set_total_height(friend_vlist_control.model_.get_total_item_height());
        local first_visible_item_index = friend_vlist_control.first_visible_item_index_;

        local id_stack_panel = friend_vlist_control.list_root_id_;
        friend_vlist_control.begin_update_visible_friend_list();

        local dynamic_stack_height = 0;
        for i = 1, #friend_vlist_control.item_list_ do
            --local p_item = ui_utility.get_ctrl_ptr_by_path(id_stack_panel, "item_" .. tostring(i));
            --local str, str_holder = U8toCUIStr("item_" .. tostring(i+first_visible_item_index));
            --p_item:SetCaption(str);
            local nodetype, ui, info, item_height = friend_vlist_control.model_.get_item_info(i-1+friend_vlist_control.first_visible_item_index_);

            friend_vlist_control.set_visible_friend_node(info);

            if nodetype == nil then
                if friend_vlist_control.item_list_[i]['frame_id'] then --隐藏节点
                    ui_utility.setproperty_by_id(friend_vlist_control.item_list_[i]['frame_id'],'Visible', 'false');
                end;
            else
                if friend_vlist_control.item_list_[i]['frame_id'] then --显示节点
                    ui_utility.setproperty_by_id(friend_vlist_control.item_list_[i]['frame_id'],'Visible', 'true');
                end;

                local ui_str, str_holder = U8toCUIStr(ui);
            
                --create node
                --friend_vlist_control.item_list_[i]['xml'] = ui;
            
                if friend_vlist_control.item_list_[i]['frame_id'] == nil then
                    nodeframe_id = layout_mgr.restore_sub_layout_multi(id_stack_panel, "social\\v_list_node.tpf");
                    friend_vlist_control.item_list_[i]['frame_id'] = nodeframe_id;
                end;

                if friend_vlist_control.item_list_[i]['vec'] == nil then
                    friend_vlist_control.item_list_[i]['vec'] = {}
                end;

                if friend_vlist_control.item_list_[i]['vec'][nodetype] == nil then
                    friend_vlist_control.item_list_[i]['vec'][nodetype] = {}
                end;

                for key, value in pairs(friend_vlist_control.item_list_[i]['vec']) do  
                    if key == nodetype then
                        if value['id'] ~= nil then
                            ui_utility.setproperty_by_id(value['id'],'Visible', 'true');
                        end;
                    else
                        if value['id'] ~= nil then
                            ui_utility.setproperty_by_id(value['id'],'Visible', 'false');
                        end;
                    end;
                end;


                if friend_vlist_control.item_list_[i]['vec'][nodetype]['id'] == nil then
                    control_id = layout_mgr.restore_sub_layout_multi(friend_vlist_control.item_list_[i]['frame_id'], ui);
                    friend_vlist_control.item_list_[i]['vec'][nodetype]['id'] = control_id;
                end;

                ui_utility.setproperty_by_id(friend_vlist_control.item_list_[i]['frame_id'], 'Height', item_height);
                friend_vlist_control.node_.update(nodetype, friend_vlist_control.item_list_[i]['vec'][nodetype]['id'], info);

                dynamic_stack_height = dynamic_stack_height + item_height;
            end;
        end
        friend_vlist_control.end_update_visible_friend_list();
        ui_utility.setproperty_by_id(id_stack_panel, 'Height', dynamic_stack_height);
        
    end;

    clicked_treenode = function()
        friend_vlist_control.model_.clicked_treenode();
        friend_vlist_control.set_total_height(friend_vlist_control.model_.get_total_item_height());
        friend_vlist_control.update_ui();
    end;
    clicked_grouptreenode = function()
        friend_vlist_control.model_.clicked_grouptreenode();
        friend_vlist_control.set_total_height(friend_vlist_control.model_.get_total_item_height());
        friend_vlist_control.update_ui();
    end;

    last_step_index_ = 0;
    fix_scrollbar_on_size_change = function()
        local id_scrollview = ui_utility.get_ctrl_parent_id(ui_utility.get_ctrl_parent_id(friend_vlist_control.list_root_id_));
        local scroll_view = ui_utility.get_ctrl_ptr_by_id(id_scrollview);
        if scroll_view ~= nil then
            local p_rc = scroll_view:GetRectEx(FALSE,TRUE);
            local new_visible_height = p_rc.bottom - p_rc.top;
            local vbar = scroll_view:GetVScrollBar();
            if vbar ~= nil then
                friend_vlist_control.set_total_height(friend_vlist_control.model_.get_total_item_height());
                vbar:SetScrollInfo(friend_vlist_control.model_.get_total_item_height(), new_visible_height, 20, friend_vlist_control.last_step_index_*20, TRUE);
                --vbar:Step(friend_vlist_control.last_step_index_);--MessageBox(friend_vlist_control.last_step_index_, "step");
            end;
        end;
    end;
    current_visible_friend_list_ = {};

    begin_update_visible_friend_list = function()
        friend_vlist_control.current_visible_friend_list_ = {};
    end;

    end_update_visible_friend_list = function()
        
    end;
    set_visible_friend_node = function(info)
        if info ~= nil and info["group_info"] ~= nil then
            local friend_id = info["group_info"].friend_id;
            table.insert(friend_vlist_control.current_visible_friend_list_, friend_id);
        end
    end;
    get_visible_friend_list = function()
        return friend_vlist_control.current_visible_friend_list_;
    end;

    update_game_state = function(event_id, json_str)
        local param = base_utility.json_to_table(json_str);
        if param.game_id == GAME_ID.GAME_ID_JH then
            friend_vlist_control.update_ui();
        end
    end;
};

friend_vlist_control.init();
